package lelouet.sh3d.plugins.sweetDatacenter.gui;

import java.awt.FlowLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;

import lelouet.datamap.DataMap;
import lelouet.datamap.Utils;
import lelouet.sh3d.plugins.sweetDatacenter.model.GridGraphicalBridge;

/** a panel that allows to generate maps from data */
public class MapManagementPanel extends JPanel implements ActionListener {

	private static final long serialVersionUID = 1L;

	protected GridGraphicalBridge bridge;

	protected JButton showCpuMap;

	protected JButton showMemMap;

	protected JButton showHeatMap;

	protected JButton loadHeatMap;

	protected JButton clearMap;

	protected float minHeat = 20;
	protected float maxHeat = 40;

	protected HeatMapPropertiesPanel heatMapInfo;

	public MapManagementPanel(GridGraphicalBridge bridge) {
		this.bridge = bridge;
		init_gui();
	}

	private void init_gui() {
		try {
			javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager
					.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		LayoutManager thislayout = new BoxLayout(this, BoxLayout.Y_AXIS);
		setLayout(thislayout);

		JPanel panLoad = new JPanel();
		panLoad.setLayout(new FlowLayout(FlowLayout.LEFT));
		{
			showCpuMap = new JButton("show cpu load");
			panLoad.add(showCpuMap);
			showCpuMap.addActionListener(this);
		}
		{
			showMemMap = new JButton("show mem load");
			panLoad.add(showMemMap);
			showMemMap.addActionListener(this);
		}
		add(panLoad);

		JPanel panHeat = new JPanel();
		panHeat.setLayout(new FlowLayout(FlowLayout.LEFT));
		{
			showHeatMap = new JButton("show heat map");
			panHeat.add(showHeatMap);
			showHeatMap.addActionListener(this);
		}
		{
			loadHeatMap = new JButton("load heat map");
			panHeat.add(loadHeatMap);
			loadHeatMap.addActionListener(this);
		}
		add(panHeat);

		{
			heatMapInfo = new HeatMapPropertiesPanel();
			panHeat.add(heatMapInfo);
		}

		{
			clearMap = new JButton("clear the map");
			add(clearMap);
			clearMap.addActionListener(this);
		}
	}

	/** last {@link DataMap} loaded that contains heat informations */
	protected DataMap heatMap = null;

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == showCpuMap) {
			bridge.showCpuMap();
		} else if (e.getSource() == showMemMap) {
			bridge.showMemMap();
		} else if (e.getSource() == showHeatMap) {
			showHeatMap();
		} else if (e.getSource() == loadHeatMap) {
			loadNewHeatMap();
		} else if (e.getSource() == clearMap) {
			bridge.clearDataMap();
		} else {
			System.out.println("uncaught action from source " + e.getSource());
		}
	}

	protected void loadNewHeatMap() {
		if (loadHeatMap()) {
			bridge.setDataMap(heatMap, minHeat, maxHeat);
		}
	}

	/**
	 * Ask the user to select a new file for the heatmap, and load it
	 * 
	 * @param forceChange
	 *            do we need to change it if there is a loaded map ? if false,
	 *            the map is reloaded whether it is new or not
	 */
	protected void showHeatMap() {
		if (heatMap == null) {
			loadHeatMap();
		}
		if (heatMap != null) {
			bridge.setDataMap(heatMap, minHeat, maxHeat);
		}

	}

	/** choser to select a file to load */
	JFileChooser fc;

	/**
	 * select a file to load the heat map from and load the {@link #heatMap}
	 * from it<br />
	 * The {@link #heatMap} is changed if the user specifies a correct map.
	 * 
	 * @return has the map been changed?
	 */
	protected boolean loadHeatMap() {
		if (fc == null) {
			fc = new JFileChooser();
			fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		}
		final int returnVal = fc.showOpenDialog(null);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			final File file = fc.getSelectedFile();
			System.out.println("loading heatmap file " + file);
			DataMap map = Utils.loadDataMap(file);
			if (map != null) {
				heatMap = map;
				return true;
			}
		}
		return false;
	}

	/** show the properties of the heatMap */
	protected class HeatMapPropertiesPanel extends JPanel {

		private static final long serialVersionUID = 1L;

		public HeatMapPropertiesPanel() {
			init_gui();
		}

		ATextFieldValidation minHeatField, maxHeatField;

		protected static final int LABEL_WIDTH = 120;
		protected static final int FIELD_WIDTH = 100;
		protected static final int ROW_HEIGHT = 20;

		@SuppressWarnings("serial")
		private void init_gui() {
			BoxLayout thislayout = new BoxLayout(this, BoxLayout.Y_AXIS);
			setLayout(thislayout);
			minHeatField = new ATextFieldValidation("min heat in °C : ",
					LABEL_WIDTH, FIELD_WIDTH, ROW_HEIGHT) {

				@Override
				public void onValidation(String text) {
					try {
						minHeat = Float.parseFloat(text);
						showHeatMap();
					} catch (NumberFormatException ex) {
						System.out.println("bad format : got " + ex.getCause()
								+ " , expected a float");
					}
				}
			};
			add(minHeatField);
			minHeatField.setText(Float.toString(minHeat));
			maxHeatField = new ATextFieldValidation("max heat in °C",
					LABEL_WIDTH, FIELD_WIDTH, ROW_HEIGHT) {

				@Override
				public void onValidation(String text) {
					try {
						maxHeat = Float.parseFloat(text);
						showHeatMap();
					} catch (NumberFormatException ex) {
						System.out.println("bad format : got " + ex.getCause()
								+ " , expected a float");
					}
				}
			};
			add(maxHeatField);
			maxHeatField.setText(Float.toString(maxHeat));
		}

	}

}
